package com.order.manager.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.order.manager.Model.UserInfo;
import com.order.manager.service.impl.UserInfoServiceImpl;
import com.order.manager.util.UUIDGeneratorUtil;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import java.util.Date;

/**
 * Spring Security 用户认证服务实现类
 * 负责根据用户名加载用户信息，并提供用户注册功能
 * 需实现 UserDetailsService 接口，作为认证流程的核心数据源
 * * UserDetailsService的实现类
 *  *String getUsername();       // 获取用户名
 *  * String getPassword();       // 获取密码（加密后）
 *  * boolean isAccountNonExpired();  // 账户是否未过期
 *  * boolean isAccountNonLocked();   // 账户是否未锁定
 *  * boolean isCredentialsNonExpired(); // 凭证是否未过期
 *  * boolean isEnabled();             // 账户是否启用
 */
@Service
@Slf4j
public class AuthUserDetailService implements UserDetailsService {

    @Resource
    private UserInfoServiceImpl userInfoService;

    /**
     * 根据用户名加载用户详细信息（Spring Security 认证核心方法）
     * @param username 登录用户名
     * @return 实现了 UserDetails 接口的用户信息对象
     * @throws UsernameNotFoundException 当用户不存在或已禁用时抛出
     */
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        // 1. 参数校验：避免空指针异常
        if (username == null) {
            throw new UsernameNotFoundException("用户名不能为空");
        }

        // 2. 查询数据库：获取状态为"启用"的用户
        UserInfo userLoginInfo = userInfoService.getOne(new QueryWrapper<UserInfo>()
                .eq("username", username)                 // 按用户名精确匹配
                //对应 SQL：WHERE state = 1
                .eq("state", '1')                       // 状态为1表示正常用户
                .eq("is_enable", "1")                   // 启用标志为1表示允许登录
        );

        // 3. 处理用户不存在或已禁用的情况
        if (userLoginInfo == null) {
            throw new UsernameNotFoundException("用户名不存在或已被禁用");
        }

        // 4. 构建安全上下文所需的用户信息对象
        UserInfo userExtendDetails = new UserInfo();
        userExtendDetails.setUsername(userLoginInfo.getUsername());  // 用户名
        userExtendDetails.setPassword(userLoginInfo.getPassword());  // 密码（已加密）
        userExtendDetails.setRole(userLoginInfo.getRole());          // 用户角色（用于权限控制）
        userExtendDetails.setIsEnable(userLoginInfo.getIsEnable());  // 账户启用状态

        // 5. 返回实现了 UserDetails 接口的用户对象
        // 注意：UserInfo 类需实现 UserDetails 接口的所有方法（如 isEnabled()、getAuthorities() 等）
        return userExtendDetails;
    }

    /**
     * 用户注册方法（处理高并发场景）
     * 生成唯一用户ID，设置创建时间，并保存到数据库
     * @param user 包含用户基本信息的实体对象
     * @return 注册成功返回完整用户信息，失败返回 null
     */
    public UserInfo insertUser(UserInfo user) {
        try {
            // 1. 生成全局唯一的用户ID（使用 UUID 避免并发冲突）
            //随机生成一个，用uuid这个特定的方法
            String userId = UUIDGeneratorUtil.generateRandomUUID();
            user.setUserId(userId);

            // 2. 设置用户创建时间（记录注册时间戳）
            user.setInputTime(new Date());

            // 3. 调用服务层保存用户信息到数据库
            // 注意：此处应确保数据库中 username 字段有唯一索引，防止并发注册同名用户
            if (userInfoService.save(user)) {
                // 注册成功，返回完整用户信息（包含自增ID等数据库生成字段）
                return user;
            }

            // 4. 保存失败返回 null
            return null;
        } catch (Exception e) {
            // 5. 异常处理：记录错误日志并返回 null
            log.error("用户注册失败: {}", e.getMessage(), e);
            return null;
        }
    }
}